package com.example.demo.game;

import com.example.demo.DemoApplication;
import com.example.demo.model.Userinfo;
import com.example.demo.service.UserService;
import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.databind.ObjectMapper;
import lombok.Data;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.socket.TextMessage;
import org.springframework.web.socket.WebSocketSession;

import java.io.IOException;
import java.util.UUID;

@Data
//代表一个人人房间类对象
public class Room {
    private String roomId;

    private Userinfo userinfo1;

    private Userinfo userinfo2;

    private Integer whiteUser;

    private int[][] arr =new int[15][15];//维护一个棋盘

    private ObjectMapper objectMapper=new ObjectMapper();

//    @Autowired
    private  GetUserLoginMatch getUserLoginMatch;

//    @Autowired
    private RoomManager roomManager;

    private UserService userService;
    public Room() {
        roomId= UUID.randomUUID().toString();
        getUserLoginMatch= DemoApplication.context.getBean(GetUserLoginMatch.class);
        roomManager=DemoApplication.context.getBean(RoomManager.class);
        userService=DemoApplication.context.getBean(UserService.class);
    }
    /**
     * 处理一次落子请求
     * @param payload
     * @throws IOException
     */
    public void putchess(String payload) throws IOException {
        ReqGame reqGame =objectMapper.readValue(payload,ReqGame.class);//获取前端传来的落子请求
        RespGame respGame =new RespGame();
        if(!reqGame.getMessage().equals("putChess")) {
            System.out.println("不符合落子请求的数据格式");
            respGame.setMessage("error");
            return;
        }
        System.out.println("服务器收到落子请求");
        int chess=reqGame.getUserid()==userinfo1.getUserid()?1:2;
        int row=reqGame.getRow();//行
        int col=reqGame.getCol();//列
        int userid=reqGame.getUserid();//落子的用户id
        if(arr[row][col]!=0) {
            System.out.println("此位置已下");
            return;
        }
        arr[row][col]=chess;
        System.out.println("行:"+row+"列:"+col);
        int winner=iswinner(chess,row,col);//获取是否胜利
        //打印当前棋盘信息
        printBoard(arr);
        //获取到对战房间中两个玩家的连接分别返回
        WebSocketSession socketSession1=getUserLoginMatch.getFromGameGame(userinfo1.getUserid());
        WebSocketSession socketSession2=getUserLoginMatch.getFromGameGame(userinfo2.getUserid());
        if(socketSession1==null) {//说明用户一掉线了
            winner=userinfo1.getUserid();//掉线直接设置对方胜利
            System.out.println("玩家一掉线");
        }
        if(socketSession2==null) {//说明用户二掉线了
            winner=userinfo2.getUserid();//掉线直接设置对方胜利
            System.out.println("玩家二掉线");
        }
        respGame.setMessage("putChess");
        respGame.setRow(row);
        respGame.setCol(col);
        respGame.setWinner(winner);
        respGame.setUserid(userid);
        System.out.println(winner);
        System.out.println("当前落子为:"+chess);
        if(socketSession1!=null) {
            socketSession1.sendMessage(new TextMessage(objectMapper.writeValueAsString(respGame)));
        }
        if(socketSession2!=null) {
            socketSession2.sendMessage(new TextMessage(objectMapper.writeValueAsString(respGame)));
        }
        //!=0说明已经分出胜负,可以销毁房间和用户连接了
        if(winner!=0) {
            System.out.println("胜负已分");
            int winuserid=respGame.getWinner();//获取胜者id
            int lostuserid=winuserid==userinfo1.getUserid()?userinfo2.getUserid():userinfo1.getUserid();
            userService.upGameadd(winuserid);
            userService.upGamedel(lostuserid);
            roomManager.remove(roomId,userinfo1,userinfo2);
        }
    }

    //打印棋盘
    private void printBoard(int[][] arr) {
        for(int i=0;i<arr.length;i++) {
            for(int j=0;j<arr[0].length;j++) {
                System.out.print(" "+arr[i][j]+" ");
            }
            System.out.println();
        }
    }

    /**
     * 判断胜负
     * @param chess
     * @param row
     * @param col
     * @return
     */
    private int iswinner(int chess, int row, int col) {
        //判断一行
            for(int c=col-4;c<=col;c++) {
                try {
                    if(arr[row][c+4]==chess
                    &&arr[row][c+3]==chess
                    &&arr[row][c+2]==chess
                    &&arr[row][c+1]==chess
                    &&arr[row][c]==chess) {
                        return chess==1?userinfo1.getUserid():userinfo2.getUserid();
                    }
                } catch (ArrayIndexOutOfBoundsException e) {
                    continue;
                }
            }
        //判断一列
        for(int r=row-4;r<=row;r++) {
            try {
                if( arr[r][col]==chess
                        && arr[r+1][col]==chess
                        &&arr[r+2][col]==chess
                        &&arr[r+3][col]==chess
                        &&arr[r+4][col]==chess) {
                    return chess==1?userinfo1.getUserid():userinfo2.getUserid();
                }
            } catch (ArrayIndexOutOfBoundsException e) {
                continue;
            }
        }
        //判断左斜
        for(int r=row-4, c=col-4;r<row&&c<col;r++,c++) {
            try {
                if(arr[r+4][c+4]==chess
                        &&arr[r+3][c+3]==chess
                        &&arr[r+2][c+2]==chess
                        &&arr[r+1][c+1]==chess
                        &&arr[r][c]==chess) {
                    return chess==1?userinfo1.getUserid():userinfo2.getUserid();
                }
            } catch (ArrayIndexOutOfBoundsException e) {
                continue;
            }
        }
        //判断右斜
        for(int r=row-4, c=col+4;r<row&&c>col;r++,c--) {
            try {
                if(arr[r+4][c-4]==chess
                        &&arr[r+3][c-3]==chess
                        &&arr[r+2][c-2]==chess
                        &&arr[r+1][c-1]==chess
                        &&arr[r][c]==chess) {
                    return chess==1?userinfo1.getUserid():userinfo2.getUserid();
                }
            } catch (ArrayIndexOutOfBoundsException e) {
                continue;
            }
        }
        //未分胜负
        return 0;
    }
}
